package com.bes.sdk.ota;

import com.bes.sdk.device.HmDevice;
import com.bes.sdk.utils.OTAStatus;

/**
 * Firmware OTA task interface. Only for OTA process initiated from app side.
 * Concrete implementation of this interface will need HmDevice and RemoteOTAConfig also.
 *
 * The APIs defined here in OTATask basically follow the Harman Lifestyle OTA Standard Flow.
 * Please refer to related document.
 */
public interface OTATask {
    /**
     * Set remoteConfig for this OTATask.
     * @param config
     */
    void setOtaConfig(RemoteOTAConfig config);
    /**
     * Get HmDevice this OTATask is running for.
     *
     * @return
     */
    HmDevice getDevice();

    /**
     * Get RemoteOTAConfig this OTATask is using.
     *
     * @return
     */
    RemoteOTAConfig getOtaConfig();

    /**
     * Get current OTATask status.
     */
    OTAStatus getOTAStatus();

    /**
     * Get current data transfer progress, number of percentage.
     */
    int getCurrentProgress();

    /**
     * Request DFU (Device Firmware Upgrade) info on device.
     * The main purpose is to check whether there was an incomplete OTA happened before. Details include:
     * - Firmware version,
     * - Breakpoint index.
     * If the version matches the latest one, app will try to resume from the breakpoint.
     * If the device holds an complete firmware, app can send a command to request APPLY it directly.
     * <p>
     * For those device doesn't support Breakpoint Resume, just return 0 that means starting from the beginning.
     */
    OTADfuInfo requestDFUInfo();

    /**
     * A plugin API to provide an opportunity to initialize the OTA data transfer.
     * For some platforms, app or client needs to explicitly tell the device such as flash address and so on.
     */
    void preTransferInit();

    /**
     * Request to start data transfer with given DFU info. With threshold 0, allowBackground true.
     * Same as startDataTransfer(dufInfo, 0, true, listener).
     *
     * @param dufInfo
     * @param listener, to the data transfer progress.
     */
    boolean startDataTransfer(OTADfuInfo dufInfo, StatusListener listener);

    /**
     * Request to start data transfer with given DFU info.
     *
     * @param dufInfo
     * @param threshold battery level threshold. OTA would be canceled once battery less than threshold.
     * @param allowBackground if allow OTA in background. In case false(don't allow in background), OTA would be canceled once app in background.
     * @param listener, to the data transfer progress.
     */
    boolean startDataTransfer(OTADfuInfo dufInfo, int threshold, boolean allowBackground, StatusListener listener);

    /**
     * Request to stop data transfer.
     * User may need to stop OTA transfer for higher priority actions.
     */
    boolean stopDataTransfer();

    /**
     * Request to paused data transfer.
     */
    boolean pausedDataTransfer();
    /**
     * A plugin API to provide an opportunity to clean up after OTA data transfer if needs.
     */
    void postTransferCleanup();

    /**
     * Request device to apply new transfer after data transfer completed.
     * @param threshold battery level threshold. OTA would not apply new firmware if battery level less than threshold.
     */
    boolean applyNewFirmware(int threshold);

    /**
     * Register data transfer listener.
     *
     * @param listener
     */
    void registerOTAStatusListener(StatusListener listener);

    /**
     * Unregister data transfer listener.
     *
     * @param listener
     */
    void unregisterOTAStatusListener(StatusListener listener);
    void disconnected();
    /**
     * OTA status listener interface.
     */
    interface StatusListener
    {
        /**
         * Callback when OTA status changed.
         */
        void onOTAStatusChanged(OTAStatus newStatus, HmDevice hmDevice);

        /**
         * Callback when OTA transfer progress changed. Transfer progress is between 0 and 100.
         * @param progress
         */
        void onOTAProgressChanged(int progress, HmDevice hmDevice);
    }
}
